package cn.geodata.dataview.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Properties;

import org.geotools.data.DataStore;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.FactoryRegistryException;
import org.geotools.factory.GeoTools;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;

public abstract class Util {
	private static Properties config;
	public static String REPOSITORY_PROPERTY_NAME = "repository.path";
		
	public static File getTomcatPath() throws IOException {
		return new File(Util.getConfigure().getProperty("tomcat.path"));
	}
	
	public static File getSpatialDataRepo() throws IOException {
		File _tomcat = Util.getTomcatPath();
		File _path1 = new File(_tomcat, "webapps\\geoserver\\data\\data");
		
		if(_path1.exists() == false){
			return new File(_tomcat, "wtpwebapps\\geoserver\\data\\data");
		}
		return _path1;
	}
	
	public static Properties getConfigure() throws IOException {
		if(config == null){
			config = new Properties();
			config.load(UtilTest.class.getResourceAsStream("/conf/Configure.txt"));
		}
		
		return config;
	}
	
	public static String combinesArray(String[] arr) {
		StringBuilder _txt = new StringBuilder();
		for(String _t : arr){
			if(_txt.length() > 0){
				_txt.append(",");
			}
			_txt.append(_t.trim());
		}
		
		return _txt.toString();
	}
	
	public static void storeConfig() throws FileNotFoundException, IOException, URISyntaxException{
		File _f = new File(Util.class.getResource("/conf/Configure.txt").toURI());
		Util.getConfigure().store(new FileOutputStream(_f), "save");
	}
	
	public static DataStore loadTmDataStore() throws IOException, URISyntaxException{
		File _tm = new File(Util.getSpatialDataRepo(), Util.getConfigure().getProperty("dataset.tm.path"));
		return new ShapefileDataStore(_tm.toURL(), new URI("http://www.geodata.cn/dataview"));
	}
	
	public static Polygon createBox(double xmin, double ymin, double xmax, double ymax){
		GeometryFactory _factory = new GeometryFactory();
		
		Coordinate[] _coordinates = new Coordinate[5];
		_coordinates[0] = new Coordinate(xmin, ymin);
		_coordinates[1] = new Coordinate(xmax, ymin);
		_coordinates[2] = new Coordinate(xmax, ymax);
		_coordinates[3] = new Coordinate(xmin, ymax);
		_coordinates[4] = new Coordinate(xmin, ymin);
		
		LinearRing _ring = _factory.createLinearRing(_coordinates);
		return _factory.createPolygon(_ring, null);
	}
	
	public static FeatureCollection locatePathRows(ArrayList<int[]> pathRow) throws IOException, IllegalAttributeException, FactoryRegistryException, SchemaException, URISyntaxException {
		DataStore _dataStore = Util.loadTmDataStore();
		FeatureType _featureType = _dataStore.getSchema(_dataStore.getTypeNames()[0]);
		
		FilterFactory2 _filterFactory = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints());
		Filter _filter = null; 
		for(int[] _pathRow : pathRow){
			Filter _c = _filterFactory.and(
					_filterFactory.equals(_filterFactory.property("PATH"), _filterFactory.literal(_pathRow[0])),
					_filterFactory.equals(_filterFactory.property("ROW"), _filterFactory.literal(_pathRow[1])));
			
			if(_filter == null){
				_filter = _c;
			}
			else{
				_filter = _filterFactory.or(_filter, _c);
			}
		}
		
		FeatureCollection _fs = _dataStore.getFeatureSource(_featureType.getTypeName()).getFeatures(_filter);
		return _fs;
//		FeatureCollection _fs2 = CommonFactoryFinder.getFeatureCollections(GeoTools.getDefaultHints()).newCollection();
//		
//		FeatureType _featureType2 = Util.copyFeatureType(_featureType);
//		FeatureIterator _it = null;
//		try{
//			ArrayList<Polygon> _polygons = new ArrayList<Polygon>();
//			_it = _fs.features();
//			while(_it.hasNext()){
//				Feature _f = _it.next();
//				_fs2.add(Util.copyFeature(_featureType2, _f));
//			}
//			
//			return _fs2;
//		}
//		finally{
//			if(_it != null){
//				_it.close();
//			}
//		}
	}
	
	public static Feature locatePathRow(int path, int row) throws IOException, IllegalAttributeException, FactoryRegistryException, SchemaException, URISyntaxException {
		DataStore _dataStore = Util.loadTmDataStore();
		FeatureType _featureType = _dataStore.getSchema(_dataStore.getTypeNames()[0]);
		
		FilterFactory2 _filterFactory = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints());
		Filter _filter = _filterFactory.and(
				_filterFactory.equals(_filterFactory.property("PATH"), _filterFactory.literal(path)),
				_filterFactory.equals(_filterFactory.property("ROW"), _filterFactory.literal(row)));
 
		FeatureCollection _fs = _dataStore.getFeatureSource(_featureType.getTypeName()).getFeatures(_filter);
		FeatureIterator _it = null;
		try{
			_it = _fs.features();
			return _it.next();
		}
		finally{
			if(_it != null){
				_it.close();
			}
		}
	}

	private static Feature copyFeature(FeatureType featureType, Feature f1) throws IllegalAttributeException {
		ArrayList<Object> _list = new ArrayList<Object>();
		for(int i=0;i<featureType.getAttributeCount();i++){
			_list.add(f1.getAttribute(i));
		}
		
		return featureType.create(_list.toArray());
	}
	
	private static FeatureType copyFeatureType(FeatureType ft) throws FactoryRegistryException, SchemaException, URISyntaxException{
		return CommonFactoryFinder.getFeatureTypeFactory(GeoTools.getDefaultHints()).newFeatureType(ft.getAttributeTypes(), "PathRow", new URI("http://www.geodata.cn/dataview"));
	}
	
	public static String[] getRepositoryPaths() throws IOException {
		String _path = Util.getConfigure().getProperty(REPOSITORY_PROPERTY_NAME);
		if(_path == null){
			return new String[0];
		}
		else{
			return _path.split("\\w*,\\w*");			
		}
	}
}
